package com.sunday.common.mq.rocket.brave.study.base.e10_Brave_Trace;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 *
 */
@Slf4j
@RestController
@RequestMapping("/test")
public class BraveTraceProducer {

    @Autowired
    private RocketTracing rocketTracing;

    @GetMapping("send")
    public void producer() throws Exception {

        // 实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer("trace_producer_group_name");
        // 设置NameServer的地址
        producer.setNamesrvAddr("127.0.0.1:9876");
        // 启动Producer实例
        producer.start();

        // 创建消息，并指定Topic，Tag和消息体
        Message message = new Message(
                "TopicTest" /* Topic */,
                "TagA" /* Tag */,
                ("Hello RocketMQ ").getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
        );
        log.info("{}", message);
        // 消息在1S内没有发送成功，就会重试
        SendResult sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
        log.info("{}", sendResult);
//        sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
//        log.info("{}", sendResult);
//        sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
//        log.info("{}", sendResult);
//        sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
//        log.info("{}", sendResult);
//        sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
//        log.info("{}", sendResult);
//        sendResult = rocketTracing.postProcessMessage(message, msg -> producer.send(msg));
        // 通过sendResult返回消息是否成功送达
//        log.info("{}", sendResult);

        // 如果不再发送消息，关闭Producer实例。
        producer.shutdown();
    }

//    public <T> T traceMessage(Message message, RocketTracing.CallbackHandler<Message, T> func) throws Exception {
//
//        MessageProducerRequest request = new MessageProducerRequest(message);
//
////        CurrentTraceContext currentTraceContext = tracing.currentTraceContext();
////        TraceContext maybeParent = currentTraceContext.get();
////        Tracer tracer = tracing.tracer();
////        Span span;
////        if (maybeParent == null) {
////            span = tracer.nextSpan().name(request.operation());
////        } else { // If we have a span in scope assume headers were cleared before
////            span = tracer.newChild(maybeParent);
////        }
//
//        Tracer tracer = tracing.tracer();
////        log.info("current span : {}", tracer.currentSpan());
//        Span span = tracer.nextSpan().name(request.operation()).start();
////        log.info("next span : {}", span);
//
////        Map<String, String> headers = new HashMap<>();
////        tracing.propagation().injector(Map<String, String>::put).inject(span.context(), headers);
////        log.info("{}", headers);
//
//        //设置brave链路信息传播行为
//        TraceContext.Injector<MessageProducerRequest> injector = tracing.propagation().injector(MessageProducerRequest.SETTER);
//        //将链路信息注入到userProperties中
//        injector.inject(span.context(), request);
//        /**
//         * span.kind是分布式追踪系统中的一个标记，用于指示跟踪操作的类型。它通常用于OpenTracing和OpenTelemetry等跟踪系统中。
//         * span.kind有两个可能的取值：
//         * client：表示跟踪操作是作为客户端发起的请求，通常用于标识发送远程调用的操作。例如，一个HTTP请求、RPC调用或发送消息到消息队列等。
//         * server：表示跟踪操作是作为服务端接收和处理请求的操作。通常用于标识处理来自客户端的请求的操作。
//         * 通过使用span.kind标记，可以在分布式系统中准确地追踪和记录请求的路径，并帮助开发人员理解请求的方向和流向。这对于性能分析、故障排查和监控系统行为非常有用。
//         */
//        span.kind(PRODUCER).name("publish");
//        maybeTag(span, ROCKET_TOPIC, message.getTopic());
//        maybeTag(span, ROCKET_TAGS, message.getTags());
//        //将span放在“范围”中，这样日志记录器等下游代码就可以看到跟踪id
////        Tracer.SpanInScope scope = tracer.withSpanInScope(span);
////        try (scope) {
//        try {
//            T res = func.doWith(message);
//            if (res != null && res instanceof SendResult result) {
//                String msgId = result.getMsgId();
//                maybeTag(span, ROCKET_MSG_ID, msgId);
//            }
//            log.info("[Response][Ack] {}", res);
//            return res;
//        } catch (Exception e) {
//            //除非您处理异常，否则您可能不知道操作失败!
//            span.error(e); //报错处理
//            log.error("[Response][Nack][ex] cause : [{}]", e.toString(), e);
//            throw e;
//        } finally {
//            //始终完成跨度
//            //注意，范围独立于跨度。一定要完成一段时间。
//            span.finish();
//        }
//    }
//
//    private void maybeTag(Span span, String tag, String value) {
//        if (value != null) span.tag(tag, value);
//    }


}
